﻿#include <string>

#include "DarkNet.h"
using namespace darknet;

static const int s_image_width        = 320;
static const int s_image_height       = 240;
static const int s_small_image_width  = 32;
static const int s_small_image_height = 24;

static bool IsRedColor(int r, int g, int b)
{
    return (r - g) > 0x20 && (r - b) > 0x20 && (g < b ? b - g : g - b) < 0x18;
}

static std::string GetRoadSignData(uint8_t *pixels)
{
    static const int s_roadsign_image_size = 200;
    int scale                              = 5;
    int width                              = s_image_width;
    int height                             = s_image_height;
    int scale_width                        = width / scale;
    int scale_height                       = height / scale;
    int scale_size                         = scale_width * scale_height;

    int offset_x = (width - s_roadsign_image_size) / 2;
    int offset_y = height - s_roadsign_image_size;
    int min_x    = width;
    int min_y    = height;
    int max_x    = 0;
    int max_y    = 0;
    for (int sy = 0; sy < scale_height; sy++)
    {
        int y = sy * scale;
        if (y < offset_y || y > (offset_y + s_roadsign_image_size)) continue;
        for (int sx = 0; sx < scale_width; sx++)
        {
            int x = sx * scale;
            if (x < offset_x || x > (offset_x + s_roadsign_image_size)) continue;
            int sum = 0;
            for (int j = 0; j < scale; j++)
            {
                for (int i = 0; i < scale; i++)
                {
                    int index = ((y + j) * width + (x + i)) * 3;
                    int r     = pixels[index];
                    int g     = pixels[index + 1];
                    int b     = pixels[index + 2];
                    if ((r - g) > 0x20 && (r - b) > 0x20 && (g < b ? b - g : g - b) < 0x18) sum++;
                }
            }
            if (sum >= (scale * scale / 2))
            {
                min_x = min_x < x ? min_x : x;
                min_y = min_y < y ? min_y : y;
                max_x = max_x < x ? x : max_x;
                max_y = max_y < y ? y : max_y;
            }
        }
    }

    if (min_x >= max_x || min_y >= max_y) return "";
    static const int extend_width  = 20;
    static const int extend_height = 10;
    float scale_x                  = (max_x - min_x + extend_width) / s_small_image_width;
    float scale_y                  = (max_y - min_y + extend_height) / s_small_image_height;
    float max_scale                = scale_x < scale_y ? scale_y : scale_x;

    int w = s_small_image_width * max_scale;
    int h = s_small_image_height * max_scale;
    int x = (max_x + min_x) / 2 - w / 2;
    int y = (max_y + min_y) / 2 - h / 2;

    std::string roadsign_data;
    roadsign_data.resize(s_small_image_width * s_small_image_height);
    for (int sy = 0; sy < s_small_image_height; sy++)
    {
        int py = sy * max_scale + y;
        if (py < 0 || py >= height) continue;
        for (int sx = 0; sx < s_small_image_width; sx++)
        {
            int px = sx * max_scale + x;
            if (px < 0 || px >= width) continue;
            int index = (py * width + px) * 3;
            int r     = pixels[index];
            int g     = pixels[index + 1];
            int b     = pixels[index + 2];
            if ((r - g) > 0x18 && (r - b) > 0x18 && (g < b ? b - g : g - b) < 0x18)
            {
                // roadsign_data[sy * s_small_image_width + sx] = 255;
                roadsign_data[sy * s_small_image_width + sx] = '1';
            }
            else
            {
                // roadsign_data[sy * s_small_image_width + sx] = 0;
                roadsign_data[sy * s_small_image_width + sx] = '0';
            }
        }
    }

    // DataImage::SaveRGB("d:/test.jpg", (unsigned char*)roadsign_data.data(), s_small_image_width, s_small_image_height, 1);

    return roadsign_data;
}

void esp_main()
{
    int width   = 0;
    int height  = 0;
    auto pixels = DataImage::LoadRGB(reinterpret_cast<const char *>(u8R"(D:/workspace/cpp/darknet/web/asset/assets/roadsigns/datasets/images/1721098761215_664.jpg)"), &width, &height);
    GetRoadSignData(pixels);
}